
#include "stdafx.h"
#include "displaytabctrl.h"

CTabItem::CTabItem(CDisplayTabCtrl* pTabCtrl)
: m_pTabCtrl(pTabCtrl)
, m_eStatus(DTS_MOUSENORMAL)
, m_eCloseStatus(DTS_MOUSENORMAL)
, m_pChildFrame(NULL)
{
}

void CTabItem::DoPaint(CDCHandle dc, CMyImage* pImage, CMyImage* pImageClose, HFONT hFont)
{
	int nWidth = pImage->GetWidth() / 3;
	int nHeight = pImage->GetHeight();

	CRect rcImage(0, 0, nWidth, nHeight);
	rcImage.MoveToXY(m_rcItem.TopLeft());
	MyDrawImagePart(dc, rcImage, *pImage, m_eStatus, 3);

	if (m_eStatus == DTS_MOUSEDOWN)
		dc.SetTextColor(RGB(255, 255, 255));
	else
		dc.SetTextColor(RGB(29, 126, 191));

	int nCloseWidth = pImageClose->GetWidth() / 3;
	int nCloseHeight = pImageClose->GetHeight();

	CRect rcImageClose(0, 0, nCloseWidth, nCloseHeight);
	rcImageClose.MoveToXY(m_rcItem.right - nCloseWidth - 4, (m_rcItem.Height() - nCloseHeight) / 2);
	MyDrawImagePart(dc, rcImageClose, *pImageClose, m_eCloseStatus, 3);

	m_rcItemClose = rcImageClose;

	CRect rcText = m_rcItem;
	rcText.left += 8;
	rcText.right = rcImageClose.left;
	dc.DrawText(GetText(), -1, &rcText, DT_LEFT | DT_VCENTER | DT_SINGLELINE | DT_WORD_ELLIPSIS | DT_NOPREFIX);
}

void CTabItem::SetText(LPCTSTR lpszText)
{
	m_strText = lpszText;
}

LPCTSTR CTabItem::GetText() const
{
	return m_strText;
}

void CTabItem::SetUrl(LPCTSTR lpszUrl)
{
	m_strUrl = lpszUrl;
}

LPCTSTR CTabItem::GetUrl() const
{
	return m_strUrl;
}

void CTabItem::SetChildFrame(CChildFrame* pChildFrame)
{
	m_pChildFrame = pChildFrame;
}

CChildFrame* CTabItem::GetChildFrame() const
{
	return m_pChildFrame;
}

void CTabItem::SetNoClose(BOOL bNoClose)
{
	m_bNoClose = bNoClose;
}

void CTabItem::SetRect(const CRect& rc)
{
	m_rcItem = rc;
}

void CTabItem::GetRect(CRect& rc) const
{
	rc = m_rcItem;
}

int CTabItem::GetWidth() const
{
	return m_rcItem.Width();
}

int CTabItem::GetHeight() const
{
	return m_rcItem.Height();
}

bool CTabItem::MouseMoveEvent(const CPoint& pt, bool bInCanvas)
{
	bool bRedraw = false;

	if (m_rcItemClose.PtInRect(pt))
	{
		if (m_eCloseStatus != DTS_MOUSEOVER)
		{
			m_eCloseStatus = DTS_MOUSEOVER;
			bRedraw = true;
		}
	}
	else if (m_eCloseStatus != DTS_MOUSENORMAL)
	{
		m_eCloseStatus = DTS_MOUSENORMAL;
		bRedraw = true;
	}

	if (!IsChecked())
	{
		if (bInCanvas && m_rcItem.PtInRect(pt))
		{
			if (m_eStatus == DTS_MOUSENORMAL)
			{
				m_eStatus = DTS_MOUSEOVER;
				bRedraw = true;
			}
		}
		else if (m_eStatus != DTS_MOUSENORMAL)
		{
			m_eStatus = DTS_MOUSENORMAL;
			bRedraw = true;
		}
	}

	return bRedraw;
}

bool CTabItem::MouseLeaveEvent()
{
	bool bRedraw = false;

	if (m_eCloseStatus != DTS_MOUSENORMAL)
	{
		m_eCloseStatus = DTS_MOUSENORMAL;
		bRedraw = true;
	}

	if (!IsChecked())
	{
		if (m_eStatus != DTS_MOUSENORMAL)
		{
			m_eStatus = DTS_MOUSENORMAL;
			bRedraw = true;
		}
	}

	return bRedraw;
}

bool CTabItem::LButtomDownEvent(const CPoint& pt, bool bInCanvas, CTabItem*& pSelectItem)
{
	if (m_rcItemClose.PtInRect(pt))
	{
		if (m_pTabCtrl)
			m_pTabCtrl->PostMessage(WM_CUSTOM_TABCLOSE, (WPARAM)this, 0);
		return true;
	}

	bool bRedraw = false;

	if (!IsChecked())
	{
		if (bInCanvas && m_rcItem.PtInRect(pt))
		{
			if (m_eStatus != DTS_MOUSEDOWN)
			{
				m_eStatus = DTS_MOUSEDOWN;

				if (pSelectItem && pSelectItem->IsChecked())
				{
					pSelectItem->CheckTab(false);
					pSelectItem = this;
				}

				if (m_pTabCtrl && m_pTabCtrl->m_pMediator)
					m_pTabCtrl->m_pMediator->ChangedShow(m_pChildFrame);
			}

			bRedraw = true;
		}
	}

	return bRedraw;
}

bool CTabItem::LButtonUpEvent(const CPoint& pt, bool bInCanvas)
{
	return false;
}

bool CTabItem::IsChecked() const
{
	return m_eStatus == DTS_MOUSEDOWN;
}

void CTabItem::CheckTab(bool bCheck)
{
	m_eStatus = bCheck ? DTS_MOUSEDOWN : DTS_MOUSENORMAL;
}

// CTabArrow
CTabArrow::CTabArrow(CDisplayTabCtrl* pTabCtrl, bool bLeft)
: m_pTabCtrl(pTabCtrl)
, m_bLeftArrow(bLeft)
, m_eStatus(DTS_MOUSENORMAL)
{
}

void CTabArrow::DoPaint(CDCHandle dc, LPRECT lpRect, CMyImage* pImage)
{
	int nWidth = pImage->GetWidth() / 4;
	int nHeight = pImage->GetHeight();

	dc.SetBkMode(TRANSPARENT);

	CRect rcImage(0, 0, nWidth, nHeight);
	rcImage.MoveToX(lpRect->left);

	MyDrawImagePart(dc, rcImage, *pImage, m_eStatus, 4);
}

void CTabArrow::SetRect(const CRect& rc)
{
	m_rcArrow = rc;
}

void CTabArrow::GetRect(CRect& rc) const
{
	rc = m_rcArrow;
}

int CTabArrow::GetWidth() const
{
	return m_rcArrow.Width();
}

int CTabArrow::GetHeight() const
{
	return m_rcArrow.Height();
}

bool CTabArrow::MouseMoveEvent(const CPoint& pt, bool bInCanvas)
{
	bool bRedraw = false;

	if (IsEnabled())
	{
		if (bInCanvas && m_rcArrow.PtInRect(pt))
		{
			if (m_eStatus == DTS_MOUSENORMAL)
			{
				m_eStatus = DTS_MOUSEOVER;
				bRedraw = true;
			}
		}
		else if (m_eStatus != DTS_MOUSENORMAL)
		{
			m_eStatus = DTS_MOUSENORMAL;
			bRedraw = true;
		}
	}

	return bRedraw;
}

bool CTabArrow::MouseLeaveEvent()
{
	bool bRedraw = false;

	if (IsEnabled())
	{
		if (m_eStatus != DTS_MOUSENORMAL)
		{
			m_eStatus = DTS_MOUSENORMAL;
			bRedraw = true;
		}
	}

	return bRedraw;
}

bool CTabArrow::LButtomDownEvent(const CPoint& pt, bool bInCanvas)
{
	bool bRedraw = false;

	if (IsEnabled())
	{
		if (bInCanvas && m_rcArrow.PtInRect(pt))
		{
			m_eStatus = DTS_MOUSEDOWN;
			if (m_pTabCtrl)
				m_pTabCtrl->PostMessage(WM_CUSTOM_ARROWCLICK, m_bLeftArrow, 0);

			bRedraw = true;
		}
	}

	return bRedraw;
}

bool CTabArrow::LButtonUpEvent(const CPoint& pt, bool bInCanvas)
{
	bool bRedraw = false;

	if (IsEnabled())
	{
		if (m_rcArrow.PtInRect(pt))
		{
			if (m_eStatus != DTS_MOUSEOVER)
			{
				m_eStatus = DTS_MOUSEOVER;
				bRedraw = true;
			}
		}
		else if (m_eStatus != DTS_MOUSENORMAL)
		{
			m_eStatus = DTS_MOUSENORMAL;
			bRedraw = true;
		}
	}

	return bRedraw;
}

bool CTabArrow::EnableArrow(bool bEnable)
{
	if (!bEnable)
	{
		if (m_eStatus != DTS_DISABLED)
		{
			m_eStatus = DTS_DISABLED;
			return true;
		}
	}
	else
	{
		if (m_eStatus == DTS_DISABLED)
		{
			m_eStatus = DTS_MOUSENORMAL;
			return true;
		}
	}
	
	return false;
}

bool CTabArrow::IsEnabled() const
{
	return m_eStatus != DTS_DISABLED;
}


// CDisplayTabCtrl
CDisplayTabCtrl::CDisplayTabCtrl()
: m_pMediator(NULL)
, m_nTabItemOffset(0)
, m_bMouseLeaveEvent(false)
, m_ArrowLeft(this, true)
, m_ArrowRight(this, false)
, m_pSelectItem(NULL)
{
}

LRESULT CDisplayTabCtrl::OnCreate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
{
	m_imgTabItem.LoadFromFile(__SF(_T("tab_item.png")));
	m_imgTabClose.LoadFromFile(__SF(_T("tab_close.png")));
	m_imgTabArrowLeft.LoadFromFile(__SF(_T("tab_arrowleft.png")));
	m_imgTabArrowRight.LoadFromFile(__SF(_T("tab_arrowright.png")));

	m_fontText.Attach(AtlGetDefaultGuiFont());

	return 0;
}

LRESULT CDisplayTabCtrl::OnDestroy(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
{
	std::vector<CTabItem *>::iterator it = m_vecTabItem.begin();
	for (; it != m_vecTabItem.end(); ++it)
	{
		delete *it;
	}

	m_vecTabItem.clear();

	return 0;
}

LRESULT CDisplayTabCtrl::OnSize(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& /*bHandled*/)
{
	CalcCanvas();

	m_ArrowLeft.SetRect(m_rcArrowLeftCanvas);
	m_ArrowRight.SetRect(m_rcArrowRightCanvas);

	CRect rcItem(0, 0, CTabItem::TABITEM_WIDTH, CTabItem::TABITEM_HEIGHT);
	rcItem.OffsetRect(m_nTabItemOffset + m_ArrowLeft.GetWidth(), 0);
	std::vector<CTabItem *>::iterator it = m_vecTabItem.begin();
	for (; it != m_vecTabItem.end(); ++it)
	{
		CTabItem* pTabItem = *it;
		pTabItem->SetRect(rcItem);
		rcItem.OffsetRect(CTabItem::TABITEM_WIDTH, 0);
	}

	RedrawArrow();

	return 0;
}

LRESULT CDisplayTabCtrl::OnMouseMove(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& /*bHandled*/)
{
	if (!m_bMouseLeaveEvent)
	{
		TRACKMOUSEEVENT tme = { sizeof(TRACKMOUSEEVENT), TME_LEAVE, m_hWnd };
		if (::TrackMouseEvent(&tme))
			m_bMouseLeaveEvent = true;
	}

	CPoint pt(lParam);

	bool bInLeftArrow = m_rcArrowLeftCanvas.PtInRect(pt) ? true : false;
	bool bInRightArrow = m_rcArrowRightCanvas.PtInRect(pt) ? true : false;
	bool bInTabItems = m_rcTabItemCanvas.PtInRect(pt) ? true : false;

	CRect rc;

	// arrow left
	if (m_ArrowLeft.MouseMoveEvent(pt, bInLeftArrow))
	{
		m_ArrowLeft.GetRect(rc);
		InvalidateRect(rc, FALSE);
	}
	
	// arrow right
	if (m_ArrowRight.MouseMoveEvent(pt, bInRightArrow))
	{
		m_ArrowRight.GetRect(rc);
		InvalidateRect(rc, FALSE);
	}

	// tab items
	std::vector<CTabItem *>::iterator it = m_vecTabItem.begin();
	for (; it != m_vecTabItem.end(); ++it)
	{
		CTabItem* pItem = *it;

		if (pItem->MouseMoveEvent(pt, bInTabItems))
		{
			pItem->GetRect(rc);
			InvalidateRect(rc, FALSE);
		}
	}

	return 0;
}

LRESULT CDisplayTabCtrl::OnMouseLeave(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
{
	m_bMouseLeaveEvent = false;

	CRect rc;

	// arrow left
	if (m_ArrowLeft.MouseLeaveEvent())
	{
		m_ArrowLeft.GetRect(rc);
		InvalidateRect(rc, FALSE);
	}

	// arrow right
	if (m_ArrowRight.MouseLeaveEvent())
	{
		m_ArrowRight.GetRect(rc);
		InvalidateRect(rc, FALSE);
	}

	// tab items
	std::vector<CTabItem *>::iterator it = m_vecTabItem.begin();
	for (; it != m_vecTabItem.end(); ++it)
	{
		CTabItem* pItem = *it;

		if (pItem->MouseLeaveEvent())
		{
			pItem->GetRect(rc);
			InvalidateRect(rc, FALSE);
		}
	}

	return 0;
}

LRESULT CDisplayTabCtrl::OnLButtonDown(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& /*bHandled*/)
{
	if (!m_bMouseLeaveEvent)
	{
		TRACKMOUSEEVENT tme = { sizeof(TRACKMOUSEEVENT), TME_LEAVE, m_hWnd };
		if (::TrackMouseEvent(&tme))
			m_bMouseLeaveEvent = true;
	}

	CPoint pt(lParam);
	
	bool bInLeftArrow = m_rcArrowLeftCanvas.PtInRect(pt) ? true : false;
	bool bInRightArrow = m_rcArrowRightCanvas.PtInRect(pt) ? true : false;
	bool bInTabItems = m_rcTabItemCanvas.PtInRect(pt) ? true : false;

	CRect rcItem;

	// arrow left
	if (m_ArrowLeft.LButtomDownEvent(pt, bInLeftArrow))
	{
		m_ArrowLeft.GetRect(rcItem);
		InvalidateRect(rcItem, FALSE);
	}

	// arrow right
	if (m_ArrowRight.LButtomDownEvent(pt, bInRightArrow))
	{
		m_ArrowRight.GetRect(rcItem);
		InvalidateRect(rcItem, FALSE);
	}

	// tab items
	std::vector<CTabItem *>::iterator it = m_vecTabItem.begin();
	for (; it != m_vecTabItem.end(); ++it)
	{
		CTabItem* pItem = *it;
		CTabItem* pOldSelected = m_pSelectItem;
		if (pItem->LButtomDownEvent(pt, bInTabItems, m_pSelectItem))
		{
			pItem->GetRect(rcItem);
			InvalidateRect(rcItem, FALSE);
			RedrawArrow();
		}

		if (!EnsureVisible(m_pSelectItem))
		{
			pOldSelected->GetRect(rcItem);
			InvalidateRect(rcItem, FALSE);
		}
	}

	return 0;
}

LRESULT CDisplayTabCtrl::OnLButtonUp(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& /*bHandled*/)
{
	CPoint pt(lParam);

	bool bInLeftArrow = m_rcArrowLeftCanvas.PtInRect(pt) ? true : false;
	bool bInRightArrow = m_rcArrowRightCanvas.PtInRect(pt) ? true : false;
	bool bInTabItems = m_rcTabItemCanvas.PtInRect(pt) ? true : false;

	CRect rc;

	// arrow left
	if (m_ArrowLeft.LButtonUpEvent(pt, bInLeftArrow))
	{
		m_ArrowLeft.GetRect(rc);
		InvalidateRect(rc, FALSE);
	}

	// arrow right
	if (m_ArrowRight.LButtonUpEvent(pt, bInRightArrow))
	{
		m_ArrowRight.GetRect(rc);
		InvalidateRect(rc, FALSE);
	}

	return 0;
}

void CDisplayTabCtrl::DoPaint(CDCHandle dc)
{	
	CRect rcClient;
	GetClientRect(&rcClient);

	dc.SetBkMode(TRANSPARENT);
	dc.SelectFont(m_fontText);

	CBrush br;
	br.CreateSolidBrush(RGB(0xff, 0xff, 0xff));
	dc.FillRect(&rcClient, br);
	MyDrawImage(&m_imgTabItem, dc, 0, 0, rcClient.Width(), m_imgTabItem.GetHeight(), 0, 0, 1, m_imgTabItem.GetHeight());

	// draw tab arrow
	m_ArrowLeft.EnableArrow(m_nTabItemOffset < 0);
	m_ArrowRight.EnableArrow((m_nTabItemOffset + (LONG)m_vecTabItem.size() * CTabItem::TABITEM_WIDTH) > m_rcArrowRightCanvas.left);

	m_ArrowLeft.DoPaint(dc, m_rcArrowLeftCanvas, &m_imgTabArrowLeft);
	m_ArrowRight.DoPaint(dc, m_rcArrowRightCanvas, &m_imgTabArrowRight);

	// draw tab item
	dc.IntersectClipRect(&m_rcTabItemCanvas);
	std::vector<CTabItem *>::iterator it = m_vecTabItem.begin();
	for (; it != m_vecTabItem.end(); ++it)
	{
		CTabItem* pTabItem = *it;
		pTabItem->DoPaint((HDC)dc, &m_imgTabItem, &m_imgTabClose, m_fontText);
	}
}

LRESULT CDisplayTabCtrl::OnCustomArrowClick(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& /*bHandled*/)
{
	bool bScrollLeft = wParam != 0;
	ScrollTabItem(bScrollLeft);

	return 0;
}

LRESULT CDisplayTabCtrl::OnCustomTabClose(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& /*bHandled*/)
{
	CTabItem* pTabItem = (CTabItem*)wParam;
	CTabItem* pNextTabItem = NULL;

	CRect rc;
	bool bFound = false;
	std::vector<CTabItem*>::iterator it = m_vecTabItem.begin();
	for (; it != m_vecTabItem.end(); ++it)
	{
		if (bFound)
		{
			if (pNextTabItem == NULL)
				pNextTabItem = *it;

			(*it)->GetRect(rc);
			rc.OffsetRect(-pTabItem->GetWidth(), 0);
			(*it)->SetRect(rc);
		}
		else
		{
			if (*it == pTabItem)
				bFound = true;
		}
	}

	if (bFound)
	{
		CChildFrame* pChildFrame = pTabItem->GetChildFrame();
		CChildFrame* pShow = NULL;

		m_vecTabItem.erase(remove(m_vecTabItem.begin(), m_vecTabItem.end(), pTabItem));
		delete pTabItem;

		if (pTabItem == m_pSelectItem)
		{
			if (pNextTabItem != NULL)
				m_pSelectItem = pNextTabItem;
			else if (!m_vecTabItem.empty())
				m_pSelectItem = m_vecTabItem.back();
			else
				m_pSelectItem = NULL;

			if (m_pSelectItem != NULL)
				m_pSelectItem->CheckTab(true);
		}

		if (!RecalcTabItemPos())
			InvalidateRect(m_rcTabItemCanvas, FALSE);

		if (m_vecTabItem.empty())
		{
			m_pMediator->ChangedQuitFrame();
		}
		else
		{
			if (m_pSelectItem)
				pShow = m_pSelectItem->GetChildFrame();

			m_pMediator->ChangedClose(pChildFrame, pShow);
		}
	}

	return 0;
}

void CDisplayTabCtrl::CalcCanvas()
{
	CWindowRect rect(m_hWnd);

	m_rcTabItemCanvas.SetRect(CTabArrow::TABARROW_WIDTH, 0, rect.Width() - CTabArrow::TABARROW_WIDTH, rect.Height());
	m_rcArrowLeftCanvas.SetRect(0, 0, CTabArrow::TABARROW_WIDTH, rect.Height());
	m_rcArrowRightCanvas.SetRect(rect.Width() - CTabArrow::TABARROW_WIDTH, 0, rect.Width(), rect.Height());
}

void CDisplayTabCtrl::RedrawArrow()
{
	InvalidateRect(m_rcArrowLeftCanvas);
	InvalidateRect(m_rcArrowRightCanvas);
}

bool CDisplayTabCtrl::EnsureVisible(CTabItem* pItem, bool bForceDraw)
{
	CalcCanvas();

	CRect rcItem;
	pItem->GetRect(rcItem);

	int nOffset = 0;
	if (rcItem.left < m_rcTabItemCanvas.left)
	{
		nOffset = m_rcTabItemCanvas.left - rcItem.left;
	}
	else if (rcItem.right > m_rcTabItemCanvas.right)
	{
		nOffset = m_rcTabItemCanvas.right - rcItem.right;
	}

	if (nOffset != 0)
	{
		std::vector<CTabItem *>::iterator it = m_vecTabItem.begin();
		for (; it != m_vecTabItem.end(); ++it)
		{
			CTabItem* pTabItem = *it;
			pTabItem->GetRect(rcItem);
			rcItem.OffsetRect(nOffset, 0);
			pTabItem->SetRect(rcItem);
		}

		m_nTabItemOffset += nOffset;
		InvalidateRect(m_rcTabItemCanvas, TRUE);

		return true;
	}
	else if (bForceDraw)
	{
		InvalidateRect(m_rcTabItemCanvas, FALSE);
		return false;
	}

	return false;
}

void CDisplayTabCtrl::ScrollTabItem(bool bLeft)
{
	int nItemWidth = CTabItem::TABITEM_WIDTH;

	CRect rc;
	int nOffset = 0;

	if (bLeft)
	{
		if (m_nTabItemOffset < 0)
		{
			if (m_nTabItemOffset < -nItemWidth)
				nOffset = nItemWidth;
			else
				nOffset = -m_nTabItemOffset;
		}
	}
	else
	{
		int nTabsWidth = 0;
		std::vector<CTabItem *>::iterator it = m_vecTabItem.begin();
		for (; it != m_vecTabItem.end(); ++it)
		{
			CTabItem* pTabItem = *it;
			nTabsWidth += pTabItem->GetWidth();
		}

		int nRightOverflow = m_nTabItemOffset + nTabsWidth - m_rcTabItemCanvas.Width();
		if (nRightOverflow > 0)
		{
			if (nRightOverflow > nItemWidth)
				nOffset = -nItemWidth;
			else
				nOffset = -nRightOverflow;
		}
	}

	if (nOffset != 0)
	{
		std::vector<CTabItem *>::iterator it = m_vecTabItem.begin();
		for (; it != m_vecTabItem.end(); ++it)
		{
			CTabItem* pTabItem = *it;
			pTabItem->GetRect(rc);
			rc.OffsetRect(nOffset, 0);
			pTabItem->SetRect(rc);
		}

		m_nTabItemOffset += nOffset;
		InvalidateRect(m_rcTabItemCanvas, TRUE);
	}
	
	RedrawArrow();
}

bool CDisplayTabCtrl::RecalcTabItemPos()
{
	int nTabsWidth = 0;
	std::vector<CTabItem *>::iterator it = m_vecTabItem.begin();
	for (; it != m_vecTabItem.end(); ++it)
	{
		CTabItem* pTabItem = *it;
		nTabsWidth += pTabItem->GetWidth();
	}

	int nOffset = 0;
	if (nTabsWidth < m_rcTabItemCanvas.Width())
	{
		nOffset = -m_nTabItemOffset;
	}
	else
	{
		if (m_nTabItemOffset > 0)
			nOffset = -m_nTabItemOffset;
		else if (m_nTabItemOffset < (m_rcTabItemCanvas.Width() - nTabsWidth))
			nOffset = m_rcTabItemCanvas.Width() - (nTabsWidth + m_nTabItemOffset);
	}

	CRect rc;

	if (nOffset != 0)
	{
		std::vector<CTabItem *>::iterator it = m_vecTabItem.begin();
		for (; it != m_vecTabItem.end(); ++it)
		{
			CTabItem* pTabItem = *it;
			pTabItem->GetRect(rc);
			rc.OffsetRect(nOffset, 0);
			pTabItem->SetRect(rc);
		}

		m_nTabItemOffset += nOffset;
		InvalidateRect(m_rcTabItemCanvas, TRUE);

		return true;
	}

	return false;
}

void CDisplayTabCtrl::AddTab(LPCTSTR lpszText, LPCTSTR lpszUrl, CChildFrame* pChildFrame, bool bSelectItem)
{
	CTabItem* pTabItem = new CTabItem(this);
	pTabItem->SetText(lpszText);
	pTabItem->SetUrl(lpszUrl);
	pTabItem->SetChildFrame(pChildFrame);

	CRect rcItem(0, 0, CTabItem::TABITEM_WIDTH, CTabItem::TABITEM_HEIGHT);
	if (m_vecTabItem.empty())
		rcItem.OffsetRect(m_nTabItemOffset + m_ArrowLeft.GetWidth(), 0);
	else
	{
		CTabItem* pLast = m_vecTabItem.back();
		CRect rcLast;
		pLast->GetRect(rcLast);
		rcItem.OffsetRect(rcLast.right, 0);
	}

	pTabItem->SetRect(rcItem);
	m_vecTabItem.push_back(pTabItem);

	if (bSelectItem)
	{
		if (m_pSelectItem)
			m_pSelectItem->CheckTab(false);

		m_pSelectItem = pTabItem;
		m_pSelectItem->CheckTab(true);
	}

	if (IsWindow())
	{
		EnsureVisible(pTabItem, true);
		RedrawArrow();
	}
}

void CDisplayTabCtrl::SetTabTitle(LPCTSTR lpszText, CChildFrame* pChildFrame)
{
	CTabItem* pTabItem = NULL;

	std::vector<CTabItem *>::iterator it = m_vecTabItem.begin();
	for (; it != m_vecTabItem.end(); ++it)
	{
		if (pChildFrame == (*it)->GetChildFrame())
		{
			pTabItem = *it;
			break;
		}
	}

	if (pTabItem != NULL)
	{
		pTabItem->SetText(lpszText);

		CRect rc;
		pTabItem->GetRect(rc);
		InvalidateRect(rc);
	}
}